/**
 * 
 */
package org.dragonfire.editor.tibasic;

import java.util.ArrayList;
import java.util.Scanner;

import org.dragonfire.editor.AttributeManager;
import org.dragonfire.editor.syntax.detectors.WhitespaceDetector;
import org.dragonfire.editor.syntax.rules.KeywordRule;
import org.dragonfire.editor.syntax.rules.LineReturnRule;
import org.dragonfire.editor.syntax.rules.PunctuationRule;
import org.dragonfire.editor.syntax.rules.StringRule;
import org.dragonfire.editor.syntax.rules.tibasic.TIBasicColumnKeywordRule;
import org.dragonfire.editor.syntax.rules.tibasic.TIBasicFunctionRule;
import org.dragonfire.ti.TIConstants;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.NumberRule;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.WhitespaceRule;
import org.eclipse.swt.SWT;

/**
 * @author Darth Android
 * @date Dec 26, 2007
 */
public class TIBasicSyntaxScanner extends RuleBasedScanner implements TIConstants {

	static {
		AttributeManager.addDefaultAttribute("ERROR", 255, 255, 255, 255, 0, 0, SWT.NONE);
		AttributeManager.addDefaultAttribute("VARIABLE", 0, 128, 0);
		AttributeManager.addDefaultAttribute("OPERATOR", 128, 128, 128);
		AttributeManager.addDefaultAttribute("FUNCTION", 0, 0, 255);
		AttributeManager.addDefaultAttribute("CONSTANT", 0, 0, 128, SWT.BOLD);
		AttributeManager.addDefaultAttribute("NUMBER", 128, 0, 128);
	}
	private static String[][] keywordLists = new String[7][];
	private static String[][] functionLists = new String[7][];
	private static String[][] variableLists = new String[7][];
	private static String[][] operatorLists = new String[7][];

	public String[] getKeywordList(int calcType) {
		switch (calcType) {
			case CALC_8X:
				keywordLists[calcType] = loadList("/resource/keywords/CALC_8X.txt");
				break;
			default:
				keywordLists[calcType] = new String[0];
		}
		return keywordLists[calcType];
	}

	public String[] getOperatorList(int calcType) {
		switch (calcType) {
			case CALC_8X:
				operatorLists[calcType] = loadList("/resource/operators/CALC_8X.txt");
				break;
			default:
				operatorLists[calcType] = new String[0];
		}
		return operatorLists[calcType];
	}

	public String[] getVariableList(int calcType) {
		switch (calcType) {
			case CALC_8X:
				variableLists[calcType] = loadList("/resource/variables/CALC_8X.txt");
				break;
			default:
				variableLists[calcType] = new String[0];
		}
		return variableLists[calcType];
	}

	public String[] getFunctionList(int calcType) {
		switch (calcType) {
			case CALC_8X:
				functionLists[calcType] = loadList("/resource/functions/CALC_8X.txt");
				break;
			default:
				functionLists[calcType] = new String[0];
		}
		return functionLists[calcType];
	}

	private static String[] loadList(String resourcePath) {
		Scanner in = new Scanner(TIBasicSyntaxScanner.class.getResourceAsStream(resourcePath));
		ArrayList<String> keywords = new ArrayList<String>();
		while (in.hasNextLine()) {
			keywords.add(in.nextLine());
		}
		return keywords.toArray(new String[keywords.size()]);
	}

	private int calcType;

	/**
	 * 
	 */
	public TIBasicSyntaxScanner(int calcType) {
		this.calcType = calcType;
		ArrayList<IRule> rules = new ArrayList<IRule>();
		/*
		 * rules.add(new SingleLineRule("\"", "->",
		 * AttributeManager.getToken("STRING")) { public IToken
		 * evaluate(ICharacterScanner scanner) { IToken tok =
		 * super.evaluate(scanner); if (tok != Token.UNDEFINED) {
		 * scanner.unread(); scanner.unread(); } return tok; } });
		 */
		rules.add(new StringRule());
		rules.add(new TIBasicColumnKeywordRule(getKeywordList(calcType), 0));
		rules.add(new TIBasicFunctionRule(getFunctionList(calcType), "FUNCTION"));
		rules.add(new KeywordRule(getOperatorList(calcType), "OPERATOR"));
		rules.add(new KeywordRule(getVariableList(calcType), "VARIABLE"));
		rules.add(new PunctuationRule());
		rules.add(new NumberRule(AttributeManager.getToken("NUMBER")));
		// rules.add(new OperatorRule());
		rules.add(new LineReturnRule());
		rules.add(new WhitespaceRule(new WhitespaceDetector()));
		setRules(rules.toArray(new IRule[rules.size()]));
		setDefaultReturnToken(AttributeManager.getToken("ERROR"));
	}
}
